/*
 * sched.h
 *
 *  Created on: 2011-3-31
 *      Author: chenl
 */

#ifndef SCHED_H_
#define SCHED_H_

#include "common/common_type.h"
#include "../priorunqueue.h"
#include <sys/types.h>

#define TASK_RUNNING			0x00
#define TASK_INTERRUPTIBLE		0x01
#define TASK_UNINTERRUPTIBLE	0x02
#define TASK_ZOMBIE				0x04
#define TASK_STOPPED			0x08
#define EXIT_ZOMBIE             16
#define EXIT_DEAD				32

/*
 * Per process flags
 */
#define PF_ALIGNWARN	0x00000001	/* Print alignment warning msgs */
					/* Not implemented yet, only for 486*/
#define PF_STARTING	0x00000002	/* being created */
#define PF_EXITING	0x00000004	/* getting shut down */
#define PF_DEAD		0x00000008	/* Dead */
#define PF_FORKNOEXEC	0x00000040	/* forked but didn't exec */
#define PF_SUPERPRIV	0x00000100	/* used super-user privileges */
#define PF_DUMPCORE	0x00000200	/* dumped core */
#define PF_SIGNALED	0x00000400	/* killed by a signal */
#define PF_MEMALLOC	0x00000800	/* Allocating memory */
#define PF_FLUSHER	0x00001000	/* responsible for disk writeback */
#define PF_USED_MATH	0x00002000	/* if unset the fpu must be initialized before use */
#define PF_FREEZE	0x00004000	/* this task is being frozen for suspend now */
#define PF_NOFREEZE	0x00008000	/* this thread should not be frozen */
#define PF_FROZEN	0x00010000	/* frozen for system suspend */
#define PF_FSTRANS	0x00020000	/* inside a filesystem transaction */
#define PF_KSWAPD	0x00040000	/* I am kswapd */
#define PF_SWAPOFF	0x00080000	/* I am in swapoff */
#define PF_LESS_THROTTLE 0x00100000	/* Throttle me less: I clean memory */
#define PF_SYNCWRITE	0x00200000	/* I am doing a sync write */
#define PF_BORROWED_MM	0x00400000	/* I am a kthread doing use_mm */
#define PF_RANDOMIZE	0x00800000	/* randomize virtual address space */

#define __set_task_state(tsk, state_value)		\
	do { (tsk)->state = (state_value); } while (0)
#define set_task_state(tsk, state_value)		\
	set_mb((tsk)->state, (state_value))

#define __set_current_state(state_value)			\
	do { current->state = (state_value); } while (0)
#define set_current_state(state_value)		\
	set_mb(current->state, (state_value))

#define NICE_TO_TICKS(nice)	(TICK_SCALE(20-(nice))+1)

#define TICK_SCALE(x)	((x) >> 2)

#define rt_task(p)     (unlikely((p)->prio < MAX_RT_PRIO))


/*
 * Scheduling policies
 */
#define SCHED_OTHER		0
#define SCHED_FIFO		1
#define SCHED_RR		2
#define SCHED_YIELD		0x10

enum
{
	enmMaxProcessNameLen 	= 256,
};

typedef CPrioRunQueue::RunQueue prio_array_t;

struct task_struct
{
	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	unsigned long flags;	/* per process flags, defined below */
	int sigpending;

	volatile long need_resched;
	long counter;
	long nice;
	unsigned long policy;

	unsigned long sleep_time;

	int prio, static_prio;
	prio_array_t *array;
	unsigned long sleep_avg;
	unsigned long long timestamp, last_ran;
    int activated;
    unsigned long nvcsw, nivcsw; /* context switch counts */

    unsigned long long sched_time;
    unsigned int time_slice, first_time_slice;

	int exit_code;
	int exit_signal;

	pid_t pid;
	pid_t pgrp;

	/*
	 * pointers to (original) parent process, youngest child, younger sibling,
	 * older sibling, respectively.  (p->father can be replaced with
	 * p->p_pptr->pid)
	 */
	struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;

//	struct task_struct* pPrev;
//	struct task_struct* pNext;
//
//	/* PID hash table linkage. */
//	struct task_struct *pidhash_next;
//	struct task_struct **pidhash_pprev;
//
//	struct task_struct* pRunQueueNext;
//	struct task_struct* pRunQueuePrev;
//
//	struct task_struct* pWaitQueueNext;
//	struct task_struct* pWaitQueuePrev;

//	struct signal_struct *sig;

//	sigset_t blocked;
//	struct sigpending pending;
};

#define INIT_TASK(tsk)

//#define pid_hashfn(x)	((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
//
//static inline void hash_pid(struct task_struct *p)
//{
//	struct task_struct **htable = &pidhash[pid_hashfn(p->pid)];
//
//	if((p->pidhash_next = *htable) != NULL)
//		(*htable)->pidhash_pprev = &p->pidhash_next;
//	*htable = p;
//	p->pidhash_pprev = htable;
//}
//
//static inline void unhash_pid(struct task_struct *p)
//{
//	if(p->pidhash_next)
//		p->pidhash_next->pidhash_pprev = p->pidhash_pprev;
//	*p->pidhash_pprev = p->pidhash_next;
//}
//
//static inline struct task_struct *find_task_by_pid(int pid)
//{
//	struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)];
//
//	for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
//		;
//	return p;
//}
//
//#define task_has_cpu(tsk) ((tsk)->cpus_runnable != ~0UL)
//
//static inline void task_set_cpu(struct task_struct *tsk, unsigned int cpu)
//{
//	tsk->processor = cpu;
//	tsk->cpus_runnable = 1UL << cpu;
//}
//
//static inline void task_release_cpu(struct task_struct *tsk)
//{
//	tsk->cpus_runnable = ~0UL;
//}
//
//static inline int signal_pending(struct task_struct *p)
//{
//	return (p->sigpending != 0);
//}

#endif /* SCHED_H_ */
